home *** CD-ROM | disk | FTP | other *** search
- Path: abcfd20.larc.nasa.gov!amiga-request
- From: amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
- Subject: v90i282: SnoopDos 1.00 - Monitors calls to AmigaDOS functions, Part01/02
- Reply-To: Eddy Carroll <ECARROLL@vax1.tcd.ie>
- Newsgroups: comp.sources.amiga
- Message-ID: <comp.sources.amiga:v90i282@abcfd20.larc.nasa.gov>
- Date: 14 Oct 90 19:07:04 GMT
- Approved: tadguy@uunet.UU.NET (Tad Guy)
- X-Mail-Submissions-To: amiga@uunet.uu.net
- X-Post-Discussions-To: comp.sys.amiga
-
- Submitted-by: Eddy Carroll <ECARROLL@vax1.tcd.ie>
- Posting-number: Volume 90, Issue 282
- Archive-name: util/snoopdos-1.0/part01
-
- [ uuencoded executable enclosed ...tad ]
-
- SnoopDos is a little utility that lets you see keep an eye on what other
- programs are doing. Specifically, it displays details of any calls a program
- makes to AmigaDOS's Open(), Lock(), LoadSeg(), Execute(), CurrentDir() and
- DeleteFile() functions.
-
- There are several uses for this. Any libraries, devices, or fonts that a
- program tries to access will be displayed, which can be useful if the
- program isn't overly generous with its error messages. Similarly, you can
- see what special startup files a program looks for. Since environment
- variables are stored as files in ENV:, you can also see what variables a
- program tries to read when you run it. In general, SnoopDos is just a handy
- utility to have around when things don't seem to be working quite right.
- As an added bonus, SnoopDos works just fine under Workbench 2.0.
-
- #!/bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 2)."
- # Contents: makefile res.s snoopdos.doc snoopdos.uu snoopglue.s
- # system.h tiny.a
- # Wrapped by tadguy@abcfd20 on Sun Oct 14 15:07:01 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'makefile'\"
- else
- echo shar: Extracting \"'makefile'\" \(799 characters\)
- sed "s/^X//" >'makefile' <<'END_OF_FILE'
- X#
- X# Lattice LKM makefile, for Lattice C V5.04 :ts=8
- X#
- X# SnoopDos (C) Copyright Eddy Carroll, May 1990
- X#
- X
- XCFLAGS = -cusq -j88i -ms -v # -d5
- XBFLAGS = sc sd nd map ram:map
- X#BFLAGS = addsym
- XLIBS = lib:lc.lib lib:amiga.lib
- XASM = lc:asm
- X#START = lib:c.o
- XSTART = tiny.o
- X
- X.c.o:
- X lc $(CFLAGS) -Hsystem.sym $*.c
- X.a.o:
- X $(ASM) -isys:include/ -u $*.a # Prefix all symbols with C-style _
- X.s.o:
- X $(ASM) -isys:include/ $*.s # Standard "pure" assembly
- X.n.doc:
- X nro >$*.doc -ms:an $*.n
- X.h.sym:
- X lc1 -ph -o$*.sym $*.h
- X
- X#
- X# Makefile dependencies
- X#
- Xall: snoopdos
- X
- XOBJS = tiny.o snoopdos.o snoopglue.o res.o
- X
- Xsnoopdos: $(OBJS)
- X blink from $(OBJS) to snoopdos $(BFLAGS) lib $(LIBS)
- X
- Xsystem.sym: system.h
- Xtiny.o: tiny.a
- Xsnoopdos.o: snoopdos.c system.sym
- Xsnoopglue.o: snoopglue.s
- Xres.o: res.s
- END_OF_FILE
- if test 799 -ne `wc -c <'makefile'`; then
- echo shar: \"'makefile'\" unpacked with wrong size!
- fi
- # end of 'makefile'
- fi
- if test -f 'res.s' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'res.s'\"
- else
- echo shar: Extracting \"'res.s'\" \(6516 characters\)
- sed "s/^X//" >'res.s' <<'END_OF_FILE'
- X*:ts=8
- X*****************************************************************************
- X* *
- X* RES.S (C) Copyright Eddy Carroll 1989 *
- X* *
- X* This module allows you to make a duplicate copy of your current process. *
- X* In fact, both processes actually share the same code. However, the *
- X* seglist pointer of the current process is modified so that when the *
- X* process terminates, the memory doesn't get freed (if it did, the new *
- X* process would suddenly find itself deallocated. Hello guru...) *
- X* This code only works when called from CLI processes. *
- X* *
- X* The parameters passed are similar to those for CreateProc(), with the *
- X* difference that instead of passing a BPTR to a seglist, you pass the *
- X* address of the function the new process should start executing at. *
- X* *
- X* When the new process returns from this function, it will be removed from *
- X* the system, and its memory (finally) deallocated. *
- X* *
- X* The typical use for a function like this is to allow a program to detach *
- X* itself from a CLI (completely, with no trailing console handles etc.) *
- X* when it is run. This is a convenient feature for the user, if the program *
- X* is of the sort designed to sit in the background the whole time, rather *
- X* than do something immediately, then exit. *
- X* *
- X* Lattice provide cback.o which at first glance would seem to provide a *
- X* similar solution. However, cback.o makes it difficult to print error *
- X* messages to the console if there is an error on the command line - by *
- X* the time you spot the error, the CLI prompt has already been printed *
- X* and your error message is printed after it. This looks very messy. *
- X* Res avoids this problem by not spawning the background process until *
- X* after the error checking has been done. *
- X* *
- X* From C, you call it as follows: *
- X* *
- X* pid = res(name,pri,func,stacksize) *
- X* *
- X* name - pointer to null terminated string *
- X* pri - integer, priority of the new process *
- X* func - pointer to the function for new process to call *
- X* stacksize - integer, size of the stack for the new process *
- X* *
- X* pid - Process ID of new process, or 0 if none created *
- X* *
- X*****************************************************************************
- X
- X INCLUDE "exec/types.i"
- X INCLUDE "exec/alerts.i"
- X INCLUDE "exec/nodes.i"
- X INCLUDE "exec/lists.i"
- X INCLUDE "exec/ports.i"
- X INCLUDE "exec/libraries.i"
- X INCLUDE "exec/tasks.i"
- X INCLUDE "libraries/dos.i"
- X INCLUDE "libraries/dosextens.i"
- X INCLUDE "workbench/startup.i"
- X INCLUDE "exec/funcdef.i"
- X INCLUDE "exec/exec_lib.i"
- X INCLUDE "libraries/dos_lib.i"
- X
- X xref _exit
- X xref _DOSBase
- X xdef _res
- X
- XAbsExecBase equ 4
- Xsegsize equ 36 ; Size of fake seg. (code = 28 bytes)
- X
- X csect text,0,0,1,2 * xref's after this are 16-bit reloc
- X
- X
- Xcallsys macro
- X CALLLIB _LVO\1
- X endm
- X
- X_res:
- X movem.l d2-d4/a2/a3/a6,-(a7) ; Save registers
- X move.l AbsExecBase.w,a6 ; Get base of Exec library
- X moveq #0,d1 ; Any sort of memory will do
- X moveq #segsize,d0 ; Get size of fake segment
- X callsys AllocMem ; Grab some memory
- X tst.l d0 ; Did we get any?
- X beq fatal ; If not, abort immediately!
- X move.l d0,a3 ; Save pointer to memory
- X sub.l a1,a1 ; NULL pointer indicates our process
- X callsys FindTask ; Get pointer to our process block
- X move.l d0,a2 ; Save it
- X move.l pr_CLI(A2),a0 ; Get BPTR to our process's segarray
- X add.l a0,a0 ; Convert BPTR to address
- X add.l a0,a0 ;
- X move.l cli_Module(a0),4(a3) ; Make fake segment point to our code
- X clr.l cli_Module(a0) ; Remove process seg. from CLI seglist
- X move.l #segsize,(a3) ; Set size of fake seglist
- X lea.l 8(a3),a2 ; Get pointer to first code byte
- X
- X;
- X; Now a tiny machine code program is constructed. It looks like this:
- X;
- X; move.l #$xxxxxx,A4 ; Initialise A4
- X; jsr $xxxxxx ; Call user program
- X; move.l #$xxxxxx,A6 ; Load DOSbase into A6
- X; move.l #$xxxxxx,d1 ; Get BPTR to this segment
- X; jmp UnLoadSeg(A6) ; Unload our process from memory
- X;
- X; It's built "on the fly" so to speak, to keep code size down, and also
- X; because it's a convenient way of initialising all the variables.
- X; Note that a potential problem exists if DOSBase should somehow alter or
- X; disappear. We'll assume it will remain relatively stable for the next
- X; few years anyway :-)
- X;
- X
- X move.l _DOSBase,a6 ; Prepare for DOS call
- X move.w #$287C,(a2)+ ; Store MOVE.L $xxxxxx,A4 instruction
- X move.l a4,(a2)+ ; Output value of A4 to initialise to
- X move.w #$4EB9,(a2)+ ; Store JSR $xxxxxx
- X move.l 36(a7),(a2)+ ; followed by address of user function
- X move.w #$2C7C,(a2)+ ; Store MOVE.L $xxxxxx,A6 instruction
- X move.l a6,(a2)+ ; followeds by current DOSbase
- X;
- X lea 4(a3),a3 ; Now get seglist ptr to fake segment
- X move.l a3,d3 ; and convert it to BPTR
- X lsr.l #2,d3 ; D3 now has seglist ptr to fake seg
- X move.w #$223C,(a2)+ ; Store MOVE.L $xxxxxx,D1 instruction
- X move.l d3,(a2)+ ; Followed by BPTR to the segment
- X move.l #$4EEEFF64,(a2)+ ; Store JMP UnLoadSeg(A6)
- X;
- X move.l 28(A7),d1 ; Get pointer to name
- X move.l 32(A7),d2 ; Get process priority
- X move.l 40(A7),d4 ; Get stacksize
- X callsys CreateProc ; Create new process
- X movem.l (a7)+,d2-d4/a2/a3/a6 ; Pop registers
- X rts ; Return
- Xfatal:
- X moveq #120,d0 ; Set error exit code
- X jmp _exit ; And exit
- X
- X end
- END_OF_FILE
- if test 6516 -ne `wc -c <'res.s'`; then
- echo shar: \"'res.s'\" unpacked with wrong size!
- fi
- # end of 'res.s'
- fi
- if test -f 'snoopdos.doc' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'snoopdos.doc'\"
- else
- echo shar: Extracting \"'snoopdos.doc'\" \(14548 characters\)
- sed "s/^X//" >'snoopdos.doc' <<'END_OF_FILE'
- X
- X SnoopDos V1.0 -- Monitors AmigaDOS function calls
- X
- X (C) Copyright Eddy Carroll, September 1990. Freely Distributable.
- X
- X
- XINTRODUCTION
- X
- X Have you ever wondered why a particular program won't seem to run?
- X It could be looking for some special files which you've forgotten to
- X install in the appropriate place. SnoopDos was designed to let you
- X resolve situations like this, though it's probably useful for other
- X things too.
- X
- X For those who don't like long instruction files, simply run SnoopDos
- X with no options, then run a few application programs and look at the
- X output displayed in SnoopDos's window. Interesting, eh? For those who'd
- X like a more detailed explanation, read on...
- X
- X When you start SnoopDos, it opens a console window. In this window
- X appears details of all calls made by any program on the system to the
- X CurrentDir(), DeleteFile, Execute(), LoadSeg(), Lock() and Open()
- X functions in the AmigaDOS library. The exception (as usual) is any
- X program written in BCPL; this includes most of the commands in the C:
- X directory.
- X
- X SnoopDos will tell you about all attempts to load libraries, devices
- X and fonts. It will also tell you if a program looks for a specific file
- X (for example in S:) or a specific disk volume or directory. This can be
- X very useful when you're playing with new software which may require
- X certain fonts or other support files.
- X
- X An unexpected bonus is that since AmigaDOS environment variables are
- X stored as files, SnoopDos will tell you the names of any environment
- X variables a program tries to read; if you see references to ENV:<name>
- X in the SnoopDos window, then a program is trying to access an environment
- X variable called <name>.
- X
- X
- XUSAGE
- X
- X When you start SnoopDos, it automatically detaches itself from the CLI
- X and runs in the background. You can specify a number of options on the
- X command line, either at this time or later on by running SnoopDos again.
- X Each option can be given in lower case or upper case to respectively
- X enable or disable that setting. Alternatively, you can follow the option
- X by `1' or `0' which has the same effect. So, `-d' and `-d1' both enable
- X the "Monitor DeleteFile()" option, whereas `-d' and `-d0' both disable
- X that option. Without further ado, here's an explanation of each setting:
- X
- X -a Normally, SnoopDos uses different colours when displaying messages,
- X to allow events to be easily distinguished from each other. You can
- X force SnoopDos not to use any colour by disabling this option. This
- X can be useful if you only have a 2-colour workbench. If SnoopDos is
- X sending its output to a file, it turns off this option by default
- X (but you can turn it back on again if you like).
- X
- X -c When this option is enabled, SnoopDos prints details of all calls
- X to the CurrentDir() function. A program calls CurrentDir() when it
- X wants to change its current directory to somewhere else. Note that
- X no result is displayed for this function, since AmigaDOS does not
- X allow for the possibility of it ever failing.
- X
- X -d This option allows you to see all calls to the DeleteFile() function,
- X which is called whenever a program wants to delete a file. This can
- X be useful with unknown programs, to make sure that they don't do
- X anything nasty (though in fairness, there are much more effective
- X ways for a rogue program to do damage than by deleting a few files).
- X
- X -f When enabled, this option causes SnoopDos to print out the full
- X path names for files. For example, if a program's current directory
- X is SYS:TOOLS and it tries to open a file called FOO, then the
- X filename would be displayed as SYS:TOOLS/FOO. Normally, it would
- X just be displayed as FOO. Filenames which are so expanded are
- X prefixed by a `>' character. Filenames which already included a full
- X path specification don't have this prefix. This allows you to
- X determine if the calling program specified the full path or not.
- X
- X -g This option enables or disables the monitoring of AmigaDOS's
- X LoadSeg() function. This is used to read in a binary loadfile and is
- X most commonly used for loading in libraries, devices, fonts and
- X handlers, and by third-party DOS shells to load in external commands.
- X
- X -l This option enables or disables the monitoring of AmigaDOS's Lock()
- X function. Programs usually call this function to see if a particular
- X file exists, or as a prelude to some more sophisticated operation on
- X the file.
- X
- X -m This option allows SnoopDos to be activated or deactivated while
- X still leaving it running. It is included merely for completeness;
- X a much easier way to achieve the same affect is to type CTRL-D or
- X CTRL-E in the SnoopDos window.
- X
- X -o This option enables or disables the monitoring of AmigaDOS's Open()
- X function. Whenever a program wants to open a file for reading or
- X writing, it calls this function.
- X
- X -w If several tasks try to call a particular DOS function at the same
- X time, SnoopDos can only handle them one at a time. Normally, what
- X will happen is that the other tasks speed on without waiting for
- X SnoopDos and you see a warning message saying that some function
- X calls were missed (this doesn't happen very often anyway). When the
- X `-w' option is enabled however, SnoopDos will make all the
- X different tasks queue up and take their turn.
- X
- X There is one important consequence of this: if a program tries to
- X access a file on a volume not currently mounted (causing AmigaDOS to
- X display a "Please insert volume xyzzy" requester), then SnoopDos will
- X print out the details about the file requested but not whether the
- X request succeeded or not; it can't do this until you respond to the
- X requester. In the meantime, other tasks may now be trying to call
- X AmigaDOS. For example, if you might try to pop open a new CLI with
- X Dmouse or PopCLI, so that you can do an ASSIGN to fake the requested
- X volume. All these tasks will have to wait until the original DOS
- X call has been completed.
- X
- X Since this can confuse things (though only for the user), the option
- X is disabled by default. You should only need it if you have to be
- X absolutely sure of catching every action made by several tasks.
- X
- X -x This option enables or disables monitoring of Execute() calls.
- X Unlike most other DOS function calls, the return value from the
- X Execute() is NOT displayed; this is because when an Execute suceeds,
- X the command being executed will most likely making AmigaDOS calls of
- X of its own and if SnoopDos was waiting for Execute() to return, it
- X would skip printing these out.
- X
- X Some forms of Execute() will appear to have no associated command
- X to execute. This is normal, and occurs when a program redirects
- X command input from another file.
- X
- X
- X By default, Snoopdos operates as if you had started it with:
- X
- X SnoopDos -a1 -c1 -d1 -f0 -g1 -l0 -m1 -o1 -w0 -x1
- X
- X or for those who prefer to use the other command format:
- X
- X SnoopDos -a -c -d -F -g -L -m -o -w -x
- X
- X There are four additional options as well, which cause immediate
- X actions to be performed. These are:
- X
- X -h Prints out a help screen for SnoopDos. Actually, typing any
- X unrecognised garbage after SnoopDos prints the help screen.
- X
- X -q Sends a message to the version of SnoopDos currently running telling
- X it to remove itself. This is one way to quit SnoopDos, the other
- X way being to type CTRL-C in its window.
- X
- X -r Prints out a brief report giving all the current settings for
- X SnoopDos (eagle-eyed users may spot a striking resemblance between
- X this display and the middle section of the help screen :-). Note
- X that all other command line options are ignored when you use -r.
- X
- X -z Allows you to specify an alternative output file for SnoopDos to
- X send messages to. The filename can follow immediately after the -z,
- X or you can leave a space if you like.
- X
- X There are several uses for this function. First of all, you can use
- X it to change the location of the SnoopDos window when it opens, by
- X specifying a filename like -zCON:0/0/640/60/SnoopDos) (for a very
- X short window). You should always make sure the window is at least 77
- X columns wide or the output will look pretty messed up.
- X
- X If you specify -zSER: or -zAUX: then SnoopDos will send output to
- X the serial port at the baud rate specified in Preferences. AUX: is
- X slightly preferable to SER: since SnoopDos will then recognise the
- X CTRL-C, CTRL-D and CTRL-E characters when typed on the remote
- X terminal. If you are using a colour ANSI terminal, you may like to
- X re-enable colour by specifying `-a' in conjunction with this option.
- X
- X Finally, you can of course redirect output to a normal AmigaDOS file.
- X You would only want to do this if you wanted to keep a permanent
- X record of what went on on your system. This could be useful if you
- X allow remote access to your Amiga and want a record of what people
- X do on your system.
- X
- X
- XTHE SNOOPDOS WINDOW
- X
- X The SnoopDos window is divided into a number of columns, as follows:
- X
- X Process name
- X The name of the process (or CLI command) that is executing the
- X DOS call in question. If the DOS call is nested (see Res. below)
- X then the process name will be prefixed by '> '.
- X
- X Func
- X The function being executed (Open, Lock or Load). Open is printed
- X in white, Lock in orange and Load in black, to allow rows to be
- X quickly identifed at a glance. (Of course, if you've changed your
- X Preferences, the actual colours may be different.) Other values
- X which can appear here are Exec (for Execute), CD (for CurrentDir)
- X and Del (for DeleteFile).
- X
- X Filename
- X The name of the file being accessed. Remember that when the `-f'
- X option is enabled, this will be prefixed by a `>' character if the
- X filename displayed was expanded by SnoopDos to include the current
- X directory of the calling process.
- X
- X Mode
- X For Open(), this is OLD if an existing file is being opened or NEW
- X if a new file is being opened. For Lock(), this is SHAR if the lock
- X is a shared lock (i.e. several processes can access the same file) or
- X EXCL if it is an exclusive lock (only this process can access the
- X file). It remains empty for LoadSeg().
- X
- X Res.
- X The result of the DOS call. This is either `Okay' in white or
- X `Fail' in orange. In general, you learn much more from the `Fail'
- X entries (i.e. the things the program tried to find but couldn't).
- X
- X Occasionally, you may see a `>>>>' appearing here. This happens if
- X some other program has also patched DOS library in such a way that
- X the function currently being called calls another DOS function
- X itself. One such program is Rez, which tries to open a program file
- X for reading if you LoadSeg() it. In this case, the `>>>>' indicates
- X that DOS calls are being nested. The DOS calls which are nested
- X will have the associated process name prefixed by `> ' when they
- X are displayed. `> (Done)' is displayed when the top level DOS
- X function exits, and the exit status is displayed on the same
- X line in the Res. column as normal.
- X
- X You can type several keys into the SnoopDos window. CTRL-C will terminate
- X SnoopDos. CTRL-D will disable monitoring temporarily (and print a brief
- X message to that effect); CTRL-E enables it again. Pressing Space or any
- X other key will pause the output to the window, as in a CLI window. Press
- X BackSpace to continue. Note that if you have the `-w' option enabled and
- X you pause the output, all functions for which monitoring is enabled will
- X cause the calling process to go to sleep until you restart output again.
- X
- X When SnoopDos wants to quit, it makes sure that nobody else has patched
- X the DOS library after it. If something has, SnoopDos will refuse to exit
- X immediately. Instead, it will check approximately every 5 seconds to
- X see if it is safe to exit and as soon as it can, it will.
- X
- X
- XHISTORY
- X
- X Version 0.9, May 28th 1990.
- X
- X Initial Beta release. No doubt people will find lots of bugs.
- X
- X Version 0.91, May 29th 1990.
- X
- X Silly bug meant Snoopdos couldn't open its console window unless
- X Conman was installed. Now fixed.
- X
- X Improved the way DOS library is patched to make it somewhat more
- X robust (it now works properly with UnixDirs).
- X
- X Version 0.92, May 31st 1990.
- X
- X Strange bug seemed to manifest itself when Rez was used; the first
- X time a resident program was loaded, the display got messed up. Turns
- X out that Rez calls Open() from within LoadSeg(). Such nesting of
- X DOS calls is now indicated by prefixing the process name printed
- X for any nested operations with a '>'. When the nesting is completed,
- X '> Done' is displayed.
- X
- X Version 0.93, June 2nd 1990.
- X
- X Added -X option to monitor Execute() calls and reworked assembly
- X language glue a bit to make it easier to modify in future.
- X
- X Version 1.00, 9th September 1990.
- X
- X First public release. After unexpectedly being sent to the US for
- X the summer (new job), I finally got around to tidying it up.
- X New features include monitoring of DeleteFile() and CurrentDir(),
- X support for alternative devices/files (such as the serial port),
- X colour now optional, a few other cosmetic changes.
- X
- X
- XAUTHOR
- X
- X Eddy Carroll
- X
- X Email: ecarroll@vax1.tcd.ie
- X Phone: +353-1-874540
- X Snailmail: The Old Rectory, Delgany, Co. Wicklow, Ireland.
- X
- X
- XDISTRIBUTION
- X
- X SnoopDos may be freely distributed as long as no charge is made other
- X than to cover time and copying costs. If you want to include SnoopDos
- X as part of a commercial package (somehow I doubt it but it never hurts
- X to mention :-) then contact the author listed above. Fred Fish is
- X specifically given permission to include SnoopDos in his fine disk
- X collection.
- END_OF_FILE
- if test 14548 -ne `wc -c <'snoopdos.doc'`; then
- echo shar: \"'snoopdos.doc'\" unpacked with wrong size!
- fi
- # end of 'snoopdos.doc'
- fi
- if test -f 'snoopdos.uu' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'snoopdos.uu'\"
- else
- echo shar: Extracting \"'snoopdos.uu'\" \(16885 characters\)
- sed "s/^X//" >'snoopdos.uu' <<'END_OF_FILE'
- Xbegin 644 snoopdos
- XM```#\P`````````"``````````$```K"```"6@```^D```K"2.=^_DOO`#0D6
- XM2"0`2?D`````+'@`!"E.`!`I3P`8D\E.KO[:)D`@#9"M``0&@````(`I0``$D
- XM0^P`)'``3J[]V"E``!QF```(<&1@``#H(&L`K-'(T<@B:``0T\G3R2`"<@`2$
- XM&2E)`"#0@5*`0F=2@`)`__Z?P%6`0G<(`"`"4X#4@1^R```@`%."4<C_]A^\V
- XM`"`@`%."'[$@`"``4<K_^")/G_P```&0)$\F2G0`831E$F?Z0>G__V$<82AFL
- XM_$(I__]@ZB!)80YA&F3\0BG__V$29OQGV"3(4D(,0@!D8R)P;F!0$!EG)@P`F
- XM`")G%@P``"!G"@P```EG!`P```H"/``>3G4`/``!`CP`^TYU+PLO`D?Y```"7
- XM('(`(#P```'28`(FP5'(__Q.NA?@<`!@!"`O``0O`"QX``0B;``<3J[^8B`?@
- XM+FP`&$S??WY.=0``+P<N+P`(("P`]%*L`/1*@&9"2JP%JF<*+RP%JDZZ(\Y8-
- XM3TJL!;)G#"(L!;(L;``<3J[_W$JL!;9G#"(L!;8L;``<3J[_W'#_OH!G""\')
- XM3KK_D%A/+A].=5!R;V-E<W,@;F%M92`@("`@("`@("!&=6YC("!&:6QE;F%MV
- XM92`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@36]D92!297,N#0HMF
- XM+2TM+2TM+2TM+2T@("`@("`@("`@+2TM+2`@+2TM+2TM+2T@("`@("`@("`@+
- XM("`@("`@("`@("`@("`@("`@("`@("TM+2T@+2TM+0T*``!/3$0@``!.15<@H
- XM```;6S,S;4Y%5QM;,&T@`%(O5R```!M;,S)M4B]7&ULP;2``/S\_(```4TA!J
- XM4@``15A#3```&ULS,VU%6$-,&ULP;0`_/S\_``!/:V%Y#0H``$9A:6P-"@```
- XM&ULS,VU&86EL&ULP;0T*`#X`&ULS,VT^&ULP;0``/B`H1&]N92D``%=A<FYI]
- XM;F<Z($UI<W-E9``;6S,S;5=A<FYI;F<Z&ULP;2!-:7-S960``#X^/CX-"@``4
- XM3W!E;@``3&]C:P``&ULS,VU,;V-K&ULP;0!,;V%D```;6S,R;4QO860;6S!M;
- XM`$5X96,``!M;,S)M17AE8QM;,&T`0T0@(```1&5L(```&ULS,VU$96P;6S!M2
- XM(`!204T`.BXN+B\`*@!3;F]O<$1O<R!0;W)T`%-N;V]P1&]S.B!#86XG="!A4
- XM;&QO8V%T92!M97-S86=E('!O<G0N"@!3;F]O<$1O<SH@0V%N)W0@86QL;V-A.
- XM=&4@96YO=6=H('-I9VYA;',N"@!3;F]O<$1O<SH@0V%N)W0@;W!E;B!F:6QE6
- XM("5S(&9O<B!O=71P=70N"@`-"E-N;V]P1&]S(%8Q+C`P("A#*2!#;W!Y<FEG:
- XM:'0@161D>2!#87)R;VQL+"!397!T(#$Y.3`N($9R965L>2!D:7-T<FEB=71A<
- XM8FQE+@T*#0H`0T]..C`O,"\V-#`O,3(P+U-N;V]P1&]S(%8Q+C`P("A#*2!#S
- XM;W!Y<FEG:'0@161D>2!#87)R;VQL+"!397!T(#$Y.3`N($9R965L>2!D:7-TO
- XM<FEB=71A8FQE+@!3;F]O<$1O<SH@0V%N)W0@;W!E;B!D:7-P;&%Y('=I;F1O-
- XM=RX*``I4>7!E($-44DPM12]#5%),+40@=&\@96YA8FQE+V1I<V%B;&4@<VYOT
- XM;W!I;F<N(%1Y<&4@0U123"U#('1O(&5X:70N"@H```I3;F]O<&EN9R!N;W<@<
- XM9&ES86)L960[('1Y<&4@0U123"U%('1O(&5N86)L92!I="!A9V%I;BX-"@T*?
- XM`%-N;V]P:6YG(&YO=R!E;F%B;&5D.R!T>7!E($-44DPM1"!T;R!D:7-A8FQE&
- XM(&ET(&%G86EN+@T*#0HE<P``/B`E<P``)2TR,7,@)7,@)7,E+3,Y<R`E<R``H
- XM`"``)2TR,7,@)7,@)7,E+30T<R``)2TR,7,@)7,@("5S#0H``"4M-S-S`"5S;
- XM(&%N($]P96XH*0T*```E<R!A($QO8VLH*0T*`"5S(&$@3&]A9%-E9R@I#0H`S
- XM`"5S(&%N($5X96-U=&4H*0T*`"5S(&$@0W5R<F5N=$1I<B@I#0H`)7,@82!$"
- XM96QE=&5&:6QE*"D-"@`-"E-O;65O;F4@96QS92!H87,@<&%T8VAE9"!D;W,N6
- XM;&EB<F%R>2!S;R!))VQL(&AA=F4@=&\@=V%I="!U;G1I;"!T:&5Y('%U:70NR
- XM#0H``%1H:7,@=VEN9&]W('=I;&P@8VQO<V4@<VAO<G1L>2!T:&]U9V@@=&\@\
- XM<W1O<"!I="!F<F]M(&%N;F]Y:6YG('EO=2X-"@`-"E-N;V]P1&]S('1E<FUII
- XM;F%T960N#0H``"UZ(&UU<W0@8F4@9F]L;&]W960@8GD@82!F:6QE;F%M92X@O
- XM5'EP92!3;F]O<$1O<R`M:"!F;W(@:&5L<"X*``!5;G)E8V]G;FES960@;W!TM
- XM:6]N("5S+B!4>7!E(%-N;V]P9&]S("UH(&9O<B!H96QP+@H`4VYO;W!$;W,@5
- XM5C$N,#`@*$,I($-O<'ER:6=H="!%9&1Y($-A<G)O;&PL(%-E<'0@,3DY,"X@@
- XM1G)E96QY(&1I<W1R:6)U=&%B;&4N"@I3;F]O<$1O<R!M;VYI=&]R<R!C86QL#
- XM<R!M861E('1O('9A<FEO=7,@06UI9V%$3U,@9G5N8W1I;VYS(&)Y(&%L;"!P8
- XM<F]C97-S97,*;VX@=&AE('-Y<W1E;2X@5&AE(&9O;&QO=VEN9R!O<'1I;VYS`
- XM(&%R92!A=F%I;&%B;&4N(%5S92`M>#$@;W(@:G5S="`M>"!T;PIE;F%B;&4@*
- XM86X@;W!T:6]N+"`M6"!O<B`M>#`@=&\@9&ES86)L92!T:&%T(&]P=&EO;BX@>
- XM0W5R<F5N="!S971T:6YG<R!I;B`H+2DN"@H`0W5R<F5N="!3;F]O<$1O<R!S6
- XM971T:6YG<SH*"@``("`@("UA("!5<V4@04Y322!C;VQO=7(@<V5Q=65N8V5SR
- XM("`@("`@("`@("`@("`@("`@("`@)7,*`"AO;BD``"AO9F8I`"`@("`M8R`@,
- XM36]N:71O<B!#=7)R96YT1&ER*"D@8V%L;',@("`@("`@("`@("`@("`@("`@J
- XM("5S"@`@("`@+60@($UO;FET;W(@1&5L971E1FEL92@I(&-A;&QS("`@("`@N
- XM("`@("`@("`@("`@("`E<PH`("`@("UF("!$:7-P;&%Y(&9U;&P@9FEL96YAM
- XM;64@<&%T:',@("`@("`@("`@("`@("`@("`@)7,*`"`@("`M9R`@36]N:71O>
- XM<B!,;V%D4V5G*"D@8V%L;',@("`@("`@("`@("`@("`@("`@("`@("5S"@`@3
- XM("`@+6P@($UO;FET;W(@3&]C:R@I(&-A;&QS("`@("`@("`@("`@("`@("`@*
- XM("`@("`@("`E<PH`("`@("UM("!';&]B86QL>2!E;F%B;&4O9&ES86)L92!M)
- XM;VYI=&]R:6YG("`@("`@("`@("`@)7,*`"`@("`M;R`@36]N:71O<B!/<&5NQ
- XM*"D@8V%L;',@("`@("`@("`@("`@("`@("`@("`@("`@("5S"@`@("`@+7<@F
- XM($1I<W!L87D@86QL(&%C=&EV:71Y+"!S;&5E<&EN9R!I9B!N96-E<W-A<GD@[
- XM("`E<PH`("`@("UX("!-;VYI=&]R($5X96-U=&4H*2!C86QL<R`@("`@("`@B
- XM("`@("`@("`@("`@("`@)7,*``H@("`@+6@@(%!R:6YT(&]U="!T:&ES(&AEK
- XM;'`@;65S<V%G90H@("`@+7$@(%1E;&P@4VYO;W!$;W,@=&\@<75I=`H@("`@?
- XM+7(@(%)E<&]R="!C=7)R96YT(%-N;V]P1&]S('-E='1I;F=S"B`@("`M>B4@:
- XM3W5T<'5T('1O(&9I;&4@)2`H92YG+B`M>D-/3CHP+S`O-C0P+S$P,"]3;F]O0
- XM<$1O<R!O<B`M>E-%4CHI"@H``%1H97)E(&ES(&YO(&)A8VMG<F]U;F0@4VYO`
- XM;W!$;W,@<')O8V5S<R!T;R!T96QL('1O('%U:70A"@!3;F]O<$1O<P``0V]UE
- XM;&1N)W0@<W!A=VX@8F%C:V=R;W5N9"!3;F]O<$1O<R!T87-K+@H`3E4``$CG4
- XM/Q`F;0`(+BT`#"PM`!`J+0`4*"T`&"\M`"`O+0`<+P0O!2\&+P<O"TAL!B).\
- XMNABJ+&P`'$ZN_\1![`8B(DA*&6;\4XF3R"(`)`@F"4ZN_]!,[0C\_^1.74YU`
- XM3E4``$CG/Q`N+0`()FT`#"PM`!`J+0`4*"T`&"\M`"0O+0`@+RT`'"\$+P4ON
- XM!B\+2&P&(DZZ&$A![`8B(DA*&6;\4XF3R"(')`@F"2QL`!Q.KO_03.T(_/_DB
- XM3EU.=4Y5_]1(YP,0+BT`""PM``PF;0`0D\DL>``$3J[^VB!`0^@`7!M\``7_K
- XMY#M\`"3_[BM)_^HK0/_P*T?_]"M&__@K2__\*T#_V"M)_]0@;`6F0^W_W$ZNH
- XM_I(@;?_43J[^@"!M_]1.KOZ,3-\(P$Y=3G5.5?[02.<W,"XM``B3R2QX``1.M
- XMKO[:($`K:`"X__@L/````2M#[?[H(@D"0?_\0JW^W'3_(4(`N"M`__PK0?[@"
- XM(@<L;``<3J[_H"H`0>P"($(P:``B!20M_N`L;``<3J[_FDJ`9@12K?[<($)0I
- XMB"M(_^Q*$&8(0_KUF"M)_^P@;?_L2AAF_%.(D>W_["`((@:2@"P!4X8K0/[8`
- XM(@5.KO\N*T#^U"(%3J[_IBHM_M1![`(@T<8O+?[8+RW_["\(3KH5LD_O``Q*W
- XMA6<4(`8B+?[8T(%![`(@$;P`+P@`8!`@!M"M_MA![`(@$;P`.@@`2H5F`/]B,
- XM(&W__"%M__@`N$JM_MQG6B`'Y8`@0"(H`!#E@2)!)"D`*.6")$)'Z@`!=@`6F
- XM$B\#+PM(;`(@*T#^V"M!_M0K0O[03KH5.G``(&W^T!`00>P"($(P``!(>O3(/
- XM2&P"($ZZ%4)![`(@(`A@"$'L`B#1QB`(3.T,[/ZT3EU.=4Y5__!(YP\P)FT`&
- XM""XM``PD;0`0*TK__'H`($I#^O2,$!BP&6842@!F]F8.($HB2Q+89OQP`&``9
- XM`+0O!V$`_E)83R!`(DL2V&;\($M*&&;\4XB1RRP(2H5F*'`ZL!)F(GH!?`!*'
- XM,V@`9PQP.K`S:`!G!%*&8.YP.K`S:`!F:%*&8&1P+[`29B8H!E6$2H1K%'`O3
- XML#-(`&<,<#JP,T@`9P13AH2H1K/BP$4H9@.$J%9B8K2O_P(&W_\$H09QIP:
- XM.K`09@X@;?_\(DL2V&;\<`!@&E*M__!@WB!+T<8B2A#99OQP`6`&4HI@`/]L\
- XM3-\,\$Y=3G5.5?_(2.<W('X`?`%Z`'``+P!(>O.D*T#_\$ZZ%FY03RE`!:IFU
- XM&$AZ\YXO+`6V80#\GDAX__]A`/%B8``)#BEL!:H%IG``(&P%IA`H``]R`20!:
- XMX:(I0@E:</\L>``$3J[^MG(!)`'AHBE""4)P_TZN_K9R`20!X:(I0@E&</].:
- XMKOZV<@$D`>&B*4()2G#_3J[^MG(!)`'AHBE""4YP_TZN_K9R`20!X:(I0@E2W
- XM</].KOZV<@'AH2E!"59P_["L"4)G'+"L"49G%K"L"4IG$+"L"4YG"K"L"5)G&
- XM!%*!9AA(>O,.+RP%MF$`^^9(>/__80#PJF``"%9*K`6Z9T9![`6^(@@D/```#
- XM`^XL;``<3J[_XBE`!;)F'$AL!;Y(>O+\+RP%MF$`^ZI(>/__80#P;F``"!I(N
- XM>O,.+RP%LF$`^Y)03V`R0?KS4"(()#P```/N+&P`'$ZN_^(I0`6R9AA(>O.2;
- XM+RP%MF$`^VA(>/__80#P+&``!]@B+`6V+&P`'$ZN_]Q"K`6V2JP%NF8.2'KSO
- XMBB\L!;)A`/LZ4$\O+``P+RP%LF$`^RQ![`5X+'@`!$ZN_=*3R4ZN_MHI0`6N?
- XM3KH.UE!/2H=F``;"("P)6H"L"4*`K`E&@*P)2H"L"4Z`K`E2@*P)5@!`$```/
- XM0"```$!``"QX``1.KO["*T#_[`@```QG`GX!"```#6<:2JP`[&<42'KS3B\LG
- XM!;)A`/JV4$]P`"E``.P(+0`&_^YG($JL`.QF&B\L`#!(>O-D+RP%LF$`^I!/M
- XM[P`,<`$I0`#L("W_["(L"4+"@&<&".T``/_S(BP)1L*`9P8([0`!__,B+`E*]
- XMPH!G!@CM``+_\R(L"4["@&<&".T``__S(BP)4L*`9P8([0`$__,B+`E6PH!GO
- XM!@CM``7_\\"L"5IG``3D(&P%IBQX``1.KOZ,*T#_Z$J`9P`$SB)`(&D`%"MH<
- XM``K_Y"(H`*SE@2MH`)C_W"M!_^!*AF8\)"D`&'8#M(-G&'8%M(-G$G8'M(-GF
- XM#'8*M(-G!G8+M(-F&GH!)"P`\.6"0>P`E"\P*``O+`6R80#YME!/2JW_X&=HX
- XM(&W_X$JH`#QG7B`H`!#E@$CM``'_S"!`$A!T`+("8VA#Z``!<``0`2\`+PE(N
- XM;`1Z3KH0ND_O``QP`"!M_\P0$$'L!'I",`@`0>P$>BM(_^1*A6<T0>P$>!"\S
- XM`#X1?``@``$K2/_D8"!*A6<<+RW_Y$AZ\D1(;`1X3KH1L$_O``Q![`1X*TC_I
- XMY"!M_^@K:``@_]1"K?_0("@`&`R`````#60``[C00#`[``9.^P`$`!@`'@`VN
- XM`$X#1`$J`T0!Y`-$`E`"?`+:`T1^`6```XYP)T'L`,PD;?_H(FH`(!+84<C_,
- XM_&```W9P)R)M_^@@:0`@0^P`S!+84<C__&```UX@;?_H("@`'`R````#[6843
- XM(BP`\"0!Y8)![``T*W`H`/_88$@,@````^YF%"(L`/`D`>6"0>P`/"MP*`#_9
- XMV&`L#(````/L9A0@+`#P(@#E@4'L`$0K<!@`_]A@$"`L`/#E@$'L`$PK<`@`%
- XM_]A*K`#D9R0@;?_H+R@`("\M_]Q(;`-,80#Z:$_O``Q![`-,*T#_T"M(_]0@*
- XM+`#PY8!*K?_09PI![`!\('`(`&`$0?KQ)B\M_]@O+?_4+PA#[`"<+S$(`"\M7
- XM_^1(>O#V+RP%LF$`]]Y/[P`<?`!@``*"(&W_Z"`H`!QR_K"!9A0B+`#P)`'E(
- XM@D'L`%0K<"@`_]A@*%*`9A0@+`#P(@#E@4'L`%PK<!@`_]A@$"`L`/#E@$'L&
- XM`&0K<`@`_]A*K`#D9R0@;?_H+R@`("\M_]Q(;`-,80#YKD_O``Q![`-,*T#_@
- XMT"M(_]0@+`#PY8!*K?_09PI![`!\('`(`&`$0?KP;"\M_]@O+?_4+PA#[`"D6
- XM+S$(`"\M_^1(>O`\+RP%LF$`]R1/[P`<?`!@``'(2JP`Y&<D(&W_Z"\H`"`OA
- XM+?_<2&P#3&$`^3Y/[P`,0>P#3"M`_]`K2/_4("P`\.6`2JW_T&<*0>P`?"!PZ
- XM"`!@!$'Z[_PO+?_4+PA#[`"L+S$(`"\M_^1(>N_H+RP%LF$`]KA/[P`8?`!@F
- XM``%<("P`\.6`+RW_U$'L`+0O,`@`+RW_Y$AZ[\XO+`6R80#VC$_O`!1\`6``7
- XM`3`@;?_H+R@`'&$`]T183R!`2AAF_%.(D<`K0/_,2.T!`/_(<B\@0"0M_\BRI
- XM,"C_9@1","C_(BP`\.6!+P!#[`"\+S$8`"\M_^1(>N]P+RP%LF$`]BY/[P`49
- XM?`%@``#22JP`Y&<D(&W_Z"\H`"`O+?_<2&P#3&$`^$A/[P`,0>P#3"M`_]`K%
- XM2/_4("P`\.6`2JW_T&<*0>P`?"!P"`!@!$'Z[P8O+?_4+PA#[`#$+S$(`"\ME
- XM_^1(>N[R+RP%LF$`]<)/[P`8?`!@9DJ&9R1*A6<@("P`\.6`0>P`A"\P"`!(Y
- XM>N[J+RP%LF$`]9A/[P`,>@`@;?_H2J@`'&<:("P`\.6`0>P`;"\P"``O+`6R,
- XM80#U<E!/8!@@+`#PY8!![`!T+S`(`"\L!;)A`/584$]\`2)M_^@L>``$3J[^\
- XMAF``^R!*K?_P9P#Z+DJ&9P#Z*`@M``#_\V<>("P`\.6`0>P`C"\P"`!(>NYL8
- XM+RP%LF$`]11/[P`,""T``?_S9QX@+`#PY8!![`",+S`(`$AZ[E8O+`6R80#TA
- XM[D_O``P(+0`"__-G'B`L`/#E@$'L`(PO,`@`2'KN/B\L!;)A`/3(3^\`#`@M#
- XM``/_\V<>("P`\.6`0>P`C"\P"`!(>NXJ+RP%LF$`]*)/[P`,""T`!/_S9QX@X
- XM+`#PY8!![`",+S`(`$AZ[A8O+`6R80#T?$_O``P(+0`%__-G'B`L`/#E@$'L3
- XM`(PO,`@`2'KN!"\L!;)A`/163^\`#$*M__!@`/D\(FP%IBQX``1.KOZ8(&P%E
- XMID*H``I.N@C`2H!F6D*M_^Q(>NW@+RP%LF$`]!Y03TJL!;IF#DAZ[APO+`6R(
- XM80#T"E!/<GW2@2QL`!Q.KO\Z2JP%LF<:4JW_[`RM`````O_L;PPB+`6R3J[_B
- XMW$*L!;).N@AF2H!GS$JL!;)G#DAZ[AHO+`6R80#SPE!/(&P%IBQX``1.KOZ,,
- XM*T#_[$J`9P@B0$ZN_H9@Y$'L!7@L>``$3J[]S'(*+&P`'$ZN_SI(>/__80#HX
- XM4DSM!.S_L$Y=3G5.5?_P2.<O,"XM``@F;0`,?`!Z`'@`0_KJ3"QX``1.KOYZW
- XM*4`%IF<22&P`S$*G2'@``6$`\Z1/[P`,<`&^@&\``8X@:P`$<BVR$&8``8)#"
- XMZ``!#!$`86400^@``G(PLA%G!BM`__!@!$*M__!#Z``!<@`2$47L`1T(,@``!
- XM&`!G"G0`%`%R(-2!8`I#Z``!<``0$20`=F&4@VT``10,@@```!IL``$*U$(T=
- XM.R`&3OL@!``R`/P`/@!(`/P`4@!<`&8`_`#\`/P`;`!V`/P`@`#\`(H`D`#\V
- XM`/P`_`#\`)8`G@#\`*8I;?_P`/!X`6```-@I;?_P`-Q@``#.*6W_\`#@8```$
- XMQ"EM__``Y&```+HI;?_P`-1@``"P?`%@``"J*6W_\`#08```H"EM__``[&``=
- XM`)8I;?_P`,Q@``",>@%@``"&?`)@``"`*6W_\`#H8'8I;?_P`-A@;B!K``14C
- XMB$H09Q!#[`6^$MAF_'`!*4`%NF`:6(M3AW`!OH!O$"!L!;HB:P`$$-EF_"E`E
- XM!;I*K`6Z9A)(>NQ080#Q@DAX``5.NN:&4$]*A&8>0JP`\&`8+RL`!$AZ['!A;
- XM`/%B2'@`!4ZZYF9/[P`,6(M3AV``_FYP`;Z`;P(L`$J&9P`!3KR`9@Q(>NQVC
- XM80#Q-%A/8`I(>NV<80#Q*%A/2JP`\&<&0?KMY&`$0?KMY"\(2'KMGF$`\0Q0$
- XM3TJL`-QG!D'Z[<A@!$'Z[<@O"$AZ[<AA`/#P4$]*K`#@9P9!^NVL8`1!^NVLO
- XM+PA(>NWF80#PU%!/2JP`Y&<&0?KMD&`$0?KMD"\(2'KN!&$`\+A03TJL`-1GO
- XM!D'Z[71@!$'Z[70O"$AZ[B)A`/"<4$]*K`#09P9!^NU88`1!^NU8+PA(>NY`U
- XM80#P@%!/2JP`[&<&0?KM/&`$0?KM/"\(2'KN7F$`\&103TJL`,QG!D'Z[2!@;
- XM!$'Z[2`O"$AZ[GQA`/!(4$]*K`#H9P9!^NT$8`1!^NT$+PA(>NZ:80#P+%!/+
- XM2JP`V&<&0?KLZ&`$0?KLZ"\(2'KNN&$`\!!03W`!O(!F"DAZ[N)A`/``6$](+
- XM>``%80#E(EA/2JP%IF<P2H5G$D*G<``O`"\`80#PG$_O``Q@$DAL`,Q"ITAX5
- XM``)A`/"(3^\`#$*G80#D[%A/2H5G$$AZ[TAA`.^R0I=A`.386$]!^N;N(@@DA
- XM/````^XL;``<3J[_XBE`!;9(>`^@2'KS'$AX``5(>N].3KH&4D_O`!!*@&826
- XM2'KO2&$`[VY(>``*80#DDE!/3-\,]$Y=3G5(YR,8)D$N`DGY`````$JL`.QG<
- XM``"`2JP`S&=XD\DL>``$3J[^VK"L!:YG:$JL`.AG"D'L!7A.KOW,8")![`5X!
- XM3J[]P$J`9A8B;`6N("P)0DZN_KPB"R0'3KH%3F`^+PLO!TAX``-A`.^P(@LDB
- XM!TZZ!3@L`$*7+P9(>``$80#OFD_O`!1![`5X+'@`!$ZN_<8@!F`((@LD!TZZ%
- XM!0Y,WQC$3G5(YR,8)D$N`DGY`````$JL`.QG``"`2JP`T&=XD\DL>``$3J[^,
- XMVK"L!:YG:$JL`.AG"D'L!7A.KOW,8")![`5X3J[]P$J`9A8B;`6N("P)1DZNY
- XM_KPB"R0'3KH$N&`^+PLO!TAX``5A`.\.(@LD!TZZ!*(L`$*7+P9(>``&80#N<
- XM^$_O`!1![`5X+'@`!$ZN_<8@!F`((@LD!TZZ!'A,WQC$3G5(YP$8)D%)^0```
- XM``!*K`#L9WI*K`#49W23R2QX``1.KO[:L*P%KF=D2JP`Z&<*0>P%>$ZN_<Q@X
- XM($'L!7A.KOW`2H!F%")L!:X@+`E*3J[^O"(+3KH$*&`Z+PM"ITAX``=A`.YR#
- XM(@M.N@04+@!"ER\'2'@`"&$`[EY/[P`40>P%>"QX``1.KOW&(`=@!B(+3KH#G
- XM[$S?&(!.=4CG,Q@F02X"+`-)^0````!*K`#L9V9*K`#89V"3R2QX``1.KO[:0
- XML*P%KF=02JP`Z&<*0>P%>$ZN_<Q@)$'L!7A.KOW`2H!F&")L!:X@+`E.3J[^1
- XMO"(+)`<F!DZZ`Y1@)B\+0J=(>``)80#MTD_O``Q![`5X+'@`!$ZN_<8B"R0'D
- XM)@9.N@-L3-\8S$YU2.<!""X!2?D`````2JP`[&=B2JP`W&=<D\DL>``$3J[^<
- XMVK"L!:YG3$JL`.AG"D'L!7A.KOW,8"!![`5X3J[]P$J`9A0B;`6N("P)4DZNE
- XM_KPB!TZZ`QQ@(D*G+P=(>``*80#M3D_O``Q![`5X+'@`!$ZN_<8B!TZZ`OA,C
- XMWQ"`3G5(YP$8)D%)^0````!*K`#L9WA*K`#@9W*3R2QX``1.KO[:L*P%KF=B#
- XM2JP`Z&<*0>P%>$ZN_<Q@($'L!7A.KOW`2H!F%")L!:X@+`E63J[^O"(+3KH"^
- XMJ&`X+PM"ITAX``MA`.S.(@M.N@*4+@!"ER\'2'@`#&$`[+I/[P`40>P%>"QX$
- XM``1.KOW&8`8B"TZZ`FY,WQB`3G5(YP#R+'D````$('D````<".@``0`.3*@.4
- XM`/_B2+D.`````/A,N0X````AXDBH#@#_XDRH#@#_K$BY#@````#^3+D.````J
- XM(>A(J`X`_ZQ,J`X`_VI(N0X````!!$RY#@```"'N2*@.`/]J3*@.`/\B2+D.L
- XM`````0I,N0X````A]$BH#@#_(DRH#@#_@DBY#@````$03+D.````(?I(J`X`A
- XM_X),J`X`_[A(N0X````!%DRY#@```"(`2*@.`/^X(DA.KOY63-]/`$YU2.<`P
- XM\BQY````!"!Y````'"`Y```AY+"H_^1F``"L(#D``"'JL*C_KF8``)X@.0``!
- XM(?"PJ/]L9@``D"`Y```A]K"H_R1F``""(#D``"'\L*C_A&8``'0@.0``(@*PU
- XMJ/^Z9@``9@CH``$`#DRY#@````#X2*@.`/_B3+D.`````/Y(J`X`_ZQ,N0X`C
- XM```!!$BH#@#_:DRY#@````$*2*@.`/\B3+D.`````1!(J`X`_X),N0X````!@
- XM%DBH#@#_N")(3J[^5G`!8`)P`$S?3P!.=4[Y```B!D[Y```B&$[Y```B*D[Y/
- XM```B/$[Y```B3D[Y```B8$CG/SY.N0``',I,WWS\(@!.=4CG/SY.N0``'6Q,'
- XMWWS\(@!.=4CG/SY.N0``'@Y,WWS\(@!.=4CG/SY.N0``'J9,WWS\(@!.=4CG1
- XM/SY.N0``'S),WWS\(@!.=4CG/SY.N0``'[),WWS\(@!.=4'Y````^#`\_^)@(
- XM/D'Y````_C`\_ZQ@,D'Y```!!#`\_VI@)D'Y```!"C`\_R)@&D'Y```!$#`\\
- XM_X)@#D'Y```!%C`\_[A@`DYQ2.=S`CP0#$9.^68``!`@:``"+'D````<3I!@,
- XMP02(9(QL%&/B@`!"QY````'-Y&3K9P!$S?0,Y.=0``2.<X,BQX``1R`'`D1
- XM3J[_.DJ`9P``;"9`D\E.KO[:)$`@:@"LT<C1R"=H`#P`!$*H`#PFO````"1%T
- XMZP`(+'D````<-/PH?"3,-/Q.N23O`"0T_"Q\),Y'ZP`$)@ODBS3\(CPDPR3\;
- XM3N[_9"(O`!PD+P`@*"\`*$ZN_W9,WTP<3G5P>$[Y```!,$CG(#`F;P`0)$M*"
- XM$F<D<``0$D'L`1T(,``!"`!G"G(`$@!T()*"8`1R`!(`%(%2BF#8(`M,WPP$/
- XM3G4``````````'!A(F\`""!O``0@+P`,(@A@!!#99PA3@&3X8`9"&%.`9/H@!
- XM`4YU(F\`""!O``0@"$H89OQ3B!#99OQ.=0``("\`""!O``1.5?_T(D]R"DZZZ
- XM`9P&00`P$L%*@&;P(`D0X;_)9OI"$)"/3EU.=0``("\`""!O``1.5?_T(D\B[
- XM``)!``<&00`P$L'FB&;P(`D0X;_)9OI"$)"/3EU.=0``,#$R,S0U-C<X.6%B)
- XM8V1E9B`O``@@;P`$0^\`!#(``D$`#Q+[$-SHB&;R(`DB#UB!$.&RB6;Z0A"08
- XM@4YU(&\`!")(<@!P`"\"#!``*V<!``+68"4D@0&`0``#!M$@P```EN#"0!B
- XMY8'2@M*!TH!@Y@P1`"UF`D2!)!\@"%.`(&\`"""!D(E.=2\'+B\`"%*L"60@4
- XM!R!L"6`0P"E("6`N'TYU3E4``$CG`#`F;P`0)&\`%$*L"60I2PE@2&T`$"\*Z
- XM2'K_QDZZ!6`@;`E@0A`@+`ED3.T,`/_X3EU.=4CG`!(F;P`,2JL`"F<*(DLL)
- XM>``$3J[^F!=\`/\`"'#_)T``%'``$"L`#RQX``1.KOZP(DMP(DZN_RY,WT@`Y
- XM3G5*@&H``!Y$@$J!:@``#$2!80``($2!3G5A```81(!$@4YU2H%J```,1(%A4
- XM```&1(!.=2\"2$$T`68``")(0$A!2$(T`&<```:$P3`"2$`T`(3!,`)(0C("H
- XM)!].=2\#=A`,00"`9```!N&944,,00@`9```!NF964,,02``9```!N6954-*7
- XM06L```;CF5-#-`#FJ$A"0D+FJDA#@,$V`#`"-`-(0<3!D()D```(4T/0@63^D
- XM<@`R`TA#Y[A(0,%!)A\D'TYU2.<#,B9O`!@N+P`<</\L>``$3J[^MBP`#`8`U
- XM_V8$<`!@9G`B(CP``0`!3J[_.B1`(`IF"G``$`9.KOZP8$@E2P`*(`<50``);
- XM%7P`!``(0BH`#A5&``^3R4ZN_MHE0``0(`MG"")*3J[^GF`:0>H`&"5(`!1!#
- XMZ@`4)4@`'$*J`!@5?``"`"`@"DS?3,!.=0``3E7_Q$CG)S`F;P!<)&\`8'X`P
- XM?`!Z`'``&WP`(/_[<@`K0?_V=/\K0O_R0>W_T!M`__$;0/_\*T'_Y"M!_^@KF
- XM2/_,2A-G+'``$!,$0``@9Q170&<444!G"%5`9A9^`6`.?`%@"GH!8`8;?``!E
- XM__Q2BV#0$!-R,+`!9@92BQM!__MP*K`39@P@4EB2*U#_]E*+8`Y(;?_V+PM.U
- XMNOTR4$_7P!`3<BZP`68B4HMP*K`39@P@4EB2*U#_\E*+8`Y(;?_R+PM.NOT('
- XM4$_7P!`3<FRP`68*&WP``?_Q4HM@"')HL`%F`E*+$!MR`!(`&T#_\`1!`%AGR
- XM``%^!$$`"V<``@I306<D!$$`"V<``1)306<``5!706<``;I506<``.1706<`1
- XM`5)@``'X2BW_\6<((%)8DB`08`8@4EB2(!`K0/_L;`IR`42M_^PK0?_H2JW_D
- XMZ&<$<"U@"DH&9P1P*V`"<"`;0/_0<``0!B(M_^B"@'``$`6"@&<(4JW_S%*M)
- XM_^0O+?_L+RW_S$ZZ^ZI03RM`_\@@+?_R2H!J!G(!*T'_\B`M_\@B+?_RDH!(%
- XM[0`"_\1O-"!M_\PB2-/!+P`O"2\(3KH"4D_O``QP`!`M__LB+?_$(&W_S&`"B
- XM$,!3@63Z("W_\BM`_\C1K?_D0>W_T"M(_\Q*!V<``3`;?``@__M@``$F2BW_E
- XM\6<((%)8DB`08`8@4EB2(!`K0/_L8`#_9$HM__%G""!26)(@$&`&(%)8DB`0+
- XM*T#_[$HM__QG$B!M_\P0_``P<@$K0?_D*TC_S"\`+RW_S$ZZ^PY03RM`_\A@M
- XM`/\R&WP`,/_[("W_\DJ`:@9P""M`__)*+?_Q9P@@4EB2(!!@!B!26)(@$"M`]
- XM_^Q*+?_\9Q8@;?_,$/P`,!#\`'AR`BM!_^0K2/_,+P`O+?_,3KKZ\E!/*T#_&
- XMR'!8L"W_\&8`_M!(;?_03KKYZEA/8`#^PB!26)(B4"M)_\QF"$'Z`-@K2/_,2
- XM(&W_S$H89OQ3B)'M_\PK2/_D("W_\DJ`:R:QP&\B*T#_Y&`<<`$K0/_D(%)8$
- XMDB`0&T#_T$(M_]%@!G``8```C"`M_^0B+?_VLH!L"'0`*T+_]F`$D:W_]DH'%
- XM9S93K?_D;1AP`"!M_\P0&"\`*TC_S"!M`!!.D%A/8.)3K?_V;4AP`!`M__LO&
- XM`"!M`!!.D%A/8.A3K?_V;1)P`!`M__LO`"!M`!!.D%A/8.A3K?_D;1AP`"!M#
- XM_\P0&"\`*TC_S"!M`!!.D%A/8.(@"TS?#.1.74YU``!.5?_T2.<!,"9O`"`D'
- XM;P`D*VT`$/_V'AI*!V<T<"6^`&8BL!)F!%**8!HO"TAM__8O"F$`_!9/[P`,+
- XM*T#_^F<$)$!@TG``$`<O`$Z36$]@QDS?#(!.74YU```@;P`$(F\`""`O``QOD
- XM%K/(90S1P-/`$R!3@&;Z3G42V%.`9OI.=0`````#[````!D````````C?```6
- XM(F8``")4```B0@``(C```"(>```B#```(@(``"'\```A]@``(?```"'J```AW
- XMY```(6H``"%<```A3@``(4```"$R```A)```(/P``"#@```@Q```(*@``"",(
- XM```@<````!\````!```C-@``(N8``"+0```A'@``(%0``"*P```BI```(I@`(
- XM`"*,```B@```(G0``"'&```AN```(:H``"&<```AC@``(8```"#T```@V```*
- XM(+P``""@```@A```(&@``!^Z```?.@``'K(``!X6```==@``'-0```$4````6
- XM#@````````/R```#Z@```(@`````````````````````````````````````X
- XM``````````!D;W,N;&EB<F%R>0````&H```"2````D@```).```"5````F(`P
- XM``)H```"=@```G8```)\```"?````H(```*(```"E@```I8```*<```"G```0
- XM`J0```*L```"O````KX```+*```"R@```M0```+D```"_@```OX```,&```#R
- XM!@```PP```,2```#(````R8```,T```#.@```T@```-(```#3@```U0````!I
- XM``````````$````!`````0````$```````````````$````!````````````&
- XM```````````````````````````````````````````@("`@("`@("`H*"@H`
- XM*"`@("`@("`@("`@("`@("`@($@0$!`0$!`0$!`0$!`0$!"$A(2$A(2$A(2$(
- XM$!`0$!`0$(&!@8&!@0$!`0$!`0$!`0$!`0$!`0$!`0$!$!`0$!`0@H*"@H*"V
- XM`@("`@("`@("`@("`@("`@("`@(0$!`0("`@("`@("`@("@H*"@H("`@("`@P
- XM("`@("`@("`@("`@2!`0$!`0$!`0$!`0$!`0$(2$A(2$A(2$A(00$!`0$!`00
- XM@8&!@8&!`0$!`0$!`0$!`0$!`0$!`0$!`0$0$!`0$!""@H*"@H("`@("`@("4
- XM`@("`@("`@("`@("`A`0$!`@```````#[````"<`````````R````,0```#`<
- XM````O````+@```"T````L````*P```"H````I````*````"<````F````)0`X
- XM``"0````C````(@```"$````@````'P```!X````=````'````!L````:```4
- XM`&0```!@````7````%@```!4````4````$P```!(````1````$`````\````P
- X1.````#0````P`````````_)4E
- X``
- Xend
- Xsize 12032
- END_OF_FILE
- if test 16885 -ne `wc -c <'snoopdos.uu'`; then
- echo shar: \"'snoopdos.uu'\" unpacked with wrong size!
- fi
- # end of 'snoopdos.uu'
- fi
- if test -f 'snoopglue.s' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'snoopglue.s'\"
- else
- echo shar: Extracting \"'snoopglue.s'\" \(5668 characters\)
- sed "s/^X//" >'snoopglue.s' <<'END_OF_FILE'
- X*
- X* SNOOPGLUE.S :ts=8
- X*
- X* Assembly support routines for snoopdos.c
- X*
- X* This file contains routines to patch/unpatch dos library to point
- X* to a C routine, and to call the old routines.
- X*
- X* Does some nasty tricks to patch into dos.library. However, since we
- X* checks to see if we are running under 2.0 (with dos.library looking
- X* just like any other library), Snoopdos works fine under 2.0.
- X*
- X INCLUDE "exec/types.i"
- X INCLUDE "exec/libraries.i"
- X INCLUDE "libraries/dosextens.i"
- X
- X XDEF _installdospatch
- X XDEF _uninstalldospatch
- X XDEF _CallLock
- X XDEF _CallOpen
- X XDEF _CallLoadSeg
- X XDEF _CallExecute
- X XDEF _CallCurrentDir
- X XDEF _CallDeleteFile
- X
- X XREF _DOSBase
- X
- X XREF _NewOpen
- X XREF _NewLock
- X XREF _NewLoadSeg
- X XREF _NewExecute
- X XREF _NewCurrentDir
- X XREF _NewDeleteFile
- X
- X XREF _LVOOpen
- X XREF _LVOLock
- X XREF _LVOLoadSeg
- X XREF _LVOExecute
- X XREF _LVOCurrentDir
- X XREF _LVODeleteFile
- X
- XCALL MACRO
- X XREF _LVO\1
- X JSR _LVO\1(A6)
- X ENDM
- X
- X SECTION SnoopDos,CODE
- X
- X*
- X* Modify DOS library to call our functions for Open() and Lock();
- X* We can't just use SetFunction() because DOS library is non-standard.
- X* Instead of using JMP $123456 type instructions, it uses (mostly)
- X* MOVEQ #funcnum,D0; BRA.L Dispatch. So, we replace this entire
- X* sequence with a standard JMP instruction, steal the number from
- X* the MOVEQ instruction and use it when we want to call the real
- X* DOS library later on.
- X*
- X_installdospatch:
- X MOVEM.L A0-A3/A6,-(A7) * Save regs
- X MOVE.L 4,A6 * Get ExecBase
- X MOVE.L _DOSBase,A0 * Get DOSbase
- X BSET #LIBB_CHANGED,LIB_FLAGS(A0) * Indicate changing DOS library
- X
- XSetFunc MACRO
- X MOVEM.W _LVO\1(A0),A1-A3 * Read in current value for func
- X MOVEM.W A1-A3,\1Save * Save the appropriate data
- X MOVEM.W CallOur\1,A1-A3 * Read in replacement code
- X MOVEM.W A1-A3,_LVO\1(A0) * And modify library
- X ENDM
- X
- X SetFunc Open
- X SetFunc Lock
- X SetFunc LoadSeg
- X SetFunc Execute
- X SetFunc CurrentDir
- X SetFunc DeleteFile
- X
- X MOVE.L A0,A1 * Finally,
- X CALL SumLibrary * Recalculate library checksum
- X MOVEM.L (A7)+,A0-A3/A6 * Save regs
- X RTS
- X
- X*
- X* Reinstall previous DOS patch. If someone has already altered the
- X* function, we can't actually exit immediately so return a FALSE
- X* result. While there is a very small window which could cause
- X* problems (if someone is in the middle of a SetFunction() when
- X* this is called), but we'll ignore this mostly.
- X*
- X_uninstalldospatch:
- X MOVEM.L A0-A3/A6,-(A7) * Save regs
- X MOVE.L 4,A6 * Get sysbase
- X MOVE.L _DOSBase,A0 * Get DOSBase
- X
- XTestFunc MACRO
- X MOVE.L CallOur\1+2,D0 * Get old address of function
- X CMP.L _LVO\1+2(A0),D0 * See if changed
- X BNE changed * If it has, exit with no action
- X ENDM
- X
- X TestFunc Open
- X TestFunc Lock
- X TestFunc LoadSeg
- X TestFunc Execute
- X TestFunc CurrentDir
- X TestFunc DeleteFile
- X
- X BSET #LIBB_CHANGED,LIB_FLAGS(A0) * Indicate changing DOS library
- X
- XRestFunc MACRO
- X MOVEM.W \1Save,A1-A3 * Read in prev. value of vec.
- X MOVEM.W A1-A3,_LVO\1(A0) * Atomically restore it
- X ENDM
- X
- X RestFunc Open
- X RestFunc Lock
- X RestFunc LoadSeg
- X RestFunc Execute
- X RestFunc CurrentDir
- X RestFunc DeleteFile
- X
- X MOVE.L A0,A1 * Finally,
- X CALL SumLibrary * Update library checksum
- X MOVEQ #1,D0 * Indicate success
- X BRA.S unexit * And exit
- X
- Xchanged:
- X MOVEQ #0,D0 * Indicate failure to uninstall
- Xunexit:
- X MOVEM.L (A7)+,A0-A3/A6 * Restore regs
- X RTS * And exit with return in D0
- X
- X*
- X* This code is the code that gets moved directly into the DOS
- X* library vectors
- X*
- XCallOurOpen: JMP NewOpen
- XCallOurLock: JMP NewLock
- XCallOurLoadSeg: JMP NewLoadSeg
- XCallOurExecute: JMP NewExecute
- XCallOurCurrentDir: JMP NewCurrentDir
- XCallOurDeleteFile: JMP NewDeleteFile
- X
- X*
- X* These are the replacement DOS routines.
- X*
- XNewFunc MACRO
- X MOVEM.L A2-A6/D2-D7,-(A7) * Save all registers (to be safe)
- X JSR _New\1 * Call C version with params in D1-D3
- X MOVEM.L (A7)+,A2-A6/D2-D7 * Restore registers
- X MOVE.L D0,D1 * Copy return value into D1
- X* * [some routines expect this :-( ]
- X RTS * Return to caller, exit value in D0
- X ENDM
- X
- XNewOpen: NewFunc Open
- XNewLock: NewFunc Lock
- XNewLoadSeg: NewFunc LoadSeg
- XNewExecute: NewFunc Execute
- XNewCurrentDir: NewFunc CurrentDir
- XNewDeleteFile: NewFunc DeleteFile
- X
- X*
- X* Allow's C to call the old DOS functions. If we're running Kikstart 2.0
- X* then just call the original function directly. Otherwise, calculate
- X* where to go from the code stored in the vector.
- X*
- XOldDosCall MACRO
- X LEA.L \1Save,A0 * Get pointer to func save vector
- X MOVE.W #_LVO\1,D0 * Get library offset vector
- X BRA.S CallDos * Skip to execute it
- X ENDM
- X
- X_CallOpen: OldDosCall Open
- X_CallLock: OldDosCall Lock
- X_CallLoadSeg: OldDosCall LoadSeg
- X_CallExecute: OldDosCall Execute
- X_CallCurrentDir: OldDosCall CurrentDir
- X_CallDeleteFile: OldDosCall DeleteFile
- X
- X NOP * Stop Lattice messing up final branch
- XCallDos:
- X MOVEM.L D1-D3/D6/D7/A6,-(A7) * Save registers
- X MOVE.W (A0),D6 * Get previous instruction
- X CMP.W #$4ef9,D6 * Is it a JMP instruction?
- X BNE dos_exec * If not, then call using special code
- X MOVE.L 2(A0),A0 * Else it's 2.0 or SetFunction()
- X MOVE.L _DOSBase,A6 * Put DOSBase into A6 as expected
- X JSR (A0) * Call original function
- X BRA.S callexit * And exit
- X
- Xdos_exec:
- X MOVE.W (A0),D6 * Get MOVEQ instruction
- X EXT.W D6 * Convert data to word
- X EXT.L D6 * and then longword
- X EXG.L D0,D6 * Swap with library vector offset
- X MOVE.W 4(A0),D7 * Get offset to DOS routine from LVO
- X MOVE.L _DOSBase,A6 * Get DOSBase
- X ADD.W D6,D7 * Calculate offset value
- X JSR 4(A6,D7.W) * Call DOS function dispatcher
- X
- Xcallexit:
- X MOVEM.L (A7)+,D1-D3/D6/D7/A6 * Restore registers
- X RTS * And return to C caller
- X
- X SECTION SnoopData,DATA
- X
- XOpenSave DS.W 3
- XLockSave DS.W 3
- XLoadSegSave DS.W 3
- XExecuteSave DS.W 3
- XCurrentDirSave DS.W 3
- XDeleteFileSave DS.W 3
- X
- X END
- END_OF_FILE
- if test 5668 -ne `wc -c <'snoopglue.s'`; then
- echo shar: \"'snoopglue.s'\" unpacked with wrong size!
- fi
- # end of 'snoopglue.s'
- fi
- if test -f 'system.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'system.h'\"
- else
- echo shar: Extracting \"'system.h'\" \(271 characters\)
- sed "s/^X//" >'system.h' <<'END_OF_FILE'
- X/* Includes for snoopdos.h */
- X
- X#include <exec/types.h>
- X#include <exec/ports.h>
- X#include <exec/semaphores.h>
- X#include <libraries/dos.h>
- X#include <libraries/dosextens.h>
- X#include <proto/exec.h>
- X#include <proto/dos.h>
- X#include <string.h>
- X#include <dos.h>
- X#include <ctype.h>
- END_OF_FILE
- if test 271 -ne `wc -c <'system.h'`; then
- echo shar: \"'system.h'\" unpacked with wrong size!
- fi
- # end of 'system.h'
- fi
- if test -f 'tiny.a' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'tiny.a'\"
- else
- echo shar: Extracting \"'tiny.a'\" \(6132 characters\)
- sed "s/^X//" >'tiny.a' <<'END_OF_FILE'
- X*:ts=8
- X****************************************************************************
- X* *
- X* TINY.A (C) Copyright Eddy Carroll 1989 *
- X* ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
- X* *
- X* Replacement startup code for Lattice C V5.04. Use instead of c.o *
- X* This has many features stripped out to allow small utilities to have *
- X* as small a filesize as possible. In particular, don't call any of the *
- X* stdio functions. *
- X* *
- X****************************************************************************
- X
- X INCLUDE "exec/types.i"
- X INCLUDE "exec/alerts.i"
- X INCLUDE "exec/nodes.i"
- X INCLUDE "exec/lists.i"
- X INCLUDE "exec/ports.i"
- X INCLUDE "exec/libraries.i"
- X INCLUDE "exec/tasks.i"
- X INCLUDE "libraries/dos.i"
- X INCLUDE "libraries/dosextens.i"
- X INCLUDE "workbench/startup.i"
- X INCLUDE "exec/funcdef.i"
- X INCLUDE "exec/exec_lib.i"
- X INCLUDE "libraries/dos_lib.i"
- X
- XMAXARGS EQU 100 ; Maximum number of command line arguments from CLI
- XAbsExecBase EQU 4 ; Welcome to the only fixed point in the universe
- X
- X* A useful macro to let us call library routines
- Xcallsys macro
- X CALLLIB _LVO\1
- X endm
- X
- X xdef XCEXIT
- X xdef exit
- X xref LinkerDB
- X xref _BSSBAS
- X xref _BSSLEN
- X
- X csect text,0,0,1,2 * xref's after this are 16-bit reloc
- X xref main * Name of C program to start with.
- X
- Xstart:
- X movem.l d1-d6/a0-a6,-(a7)
- XREGSIZE EQU (6+7)*4
- X lea REGSIZE(a7),A5 * Determine old stack pointer
- X move.l a0,a2 * Save command pointer
- X move.l d0,d2 * and command length
- X lea LinkerDB,a4 * Load base register
- X
- X move.l AbsExecBase.W,a6
- X move.l a6,SysBase(A4)
- X move.l a7,_StackPtr(A4) * Save stack ptr
- X
- X suba.l a1,a1
- X callsys FindTask * Find out our task ID
- X move.l d0,a3
- X
- X move.l a5,D0 * get top of stack
- X sub.l 4(a5),D0 * compute bottom
- X add.l #128,D0 * allow for parms overflow
- X move.l D0,_base(A4) * save for stack checking
- X
- X lea DOSName(A4),A1
- X moveq.l #0,D0
- X callsys OpenLibrary
- X move.l D0,DOSBase(A4)
- X bne getcom
- XnoDOS:
- X moveq.l #100,d0
- X bra exit2
- X
- X*------ find command name:
- Xgetcom:
- X move.l pr_CLI(a3),a0
- X add.l a0,a0
- X add.l a0,a0
- X move.l cli_CommandName(a0),a1
- X add.l a1,a1
- X add.l a1,a1
- X
- X*------ collect parameters:
- X move.l d2,d0 * get command line length
- X moveq.l #0,d1
- X move.b (a1)+,d1
- X move.l a1,_ProgramName(A4)
- X add.l d1,d0 * add length of command name
- X addq.l #1,d0 * allow for space after command
- X
- X clr.w -(A7) * set null terminator for command line
- X addq.l #1,D0 * force to even number of bytes
- X andi.w #$fffe,D0 * (round up)
- X sub.l D0,A7 * make room on stack for command line
- X subq.l #2,D0
- X clr.w 0(A7,D0)
- X
- X*------ copy command line onto stack
- X move.l d2,d0 * get command line length
- X subq.l #1,d0
- X add.l d1,d2
- X
- Xcopy_line:
- X move.b 0(A2,D0.W),0(A7,D2.W) * copy command line to stack
- X subq.l #1,d2
- X dbf d0,copy_line
- X move.b #' ',0(a7,d2.w) * add space between command and parms
- X subq.l #1,d2
- X
- Xcopy_cmd:
- X move.b 0(a1,d2.w),0(a7,d2.w) * copy command name to stack
- X dbf d2,copy_cmd
- X move.l a7,a1 * Get pointer to new command line
- X
- X sub.l #(MAXARGS*4),a7 * Reserve space for argv[]
- X move.l a7,a2 * Initialise base into array
- X move.l a2,a3 * Save base of argv
- X moveq #0,d2 * Initialise argc
- X
- X*
- X* From here on down, A1 is pointer into command line
- X*
- Xbuild_argv:
- X bsr.s getnext * Read next character from line
- X bcs.s doquote * If quote, handle
- X beq.s build_argv * If white space, skip over it
- X
- X lea -1(a1),a0 * Get address of this parameter
- X bsr.s bumpargv * Store it to argv[] array
- Xbuild_2:
- X bsr.s getnext * Get next character
- X bne.s build_2 * If not white space, keep looking
- X clr.b -1(a1) * Zero-terminate current argument
- X bra.s build_argv * And go back to get next argument
- X
- Xdoquote:
- X move.l a1,a0 * Get pointer to this argument
- X bsr.s bumpargv * Output it to argv[]
- Xquote_2:
- X bsr.s getnext * Get next character
- X bcc.s quote_2 * If not quote, keep looking
- X clr.b -1(a1) * Zero-terminate current argument
- Xquote_3:
- X bsr.s getnext * Get next character
- X bne.s quote_3 * Skip until space reached
- X beq.s build_argv * Go back and read next argument
- X
- Xbumpargv:
- X move.l a0,(a2)+ * Output ptr to current argument
- X addq #1,d2 * Increment argc
- X cmpi #MAXARGS,d2 * Used up all our arguments yet?
- X bls.s qrts * If not, then return
- X moveq #110,d0 * Else set return code
- X bra.s exit2 * And exit
- X
- X*
- X* Reads next character from command line. If zero, never returns, but
- X* drops into call to main. Else, returns, with C=1 if character is quote,
- X* Z=1 if character is white space.
- X*
- Xgetnext:
- X move.b (a1)+,d0 * Get character from command line
- X beq.s get_2 * Exit if end of line
- X cmp.b #34,d0 * Check if quote
- X beq.s isquote *
- X cmp.b #32,d0 * Check if space
- X beq.s isspace *
- X cmp.b #9,d0 * Or tab
- X beq.s isspace *
- X cmp.b #10,d0 * Or end of line
- Xisspace:
- X andi #$1E,ccr * Clear carry flag, retaining Z
- Xqrts rts
- X
- Xisquote:
- X ori #1,ccr * Set carry flag
- X andi #$FB,ccr * Clear zero flag
- X rts * And return
- X
- Xget_2:
- X move.l a3,-(a7) * Push argv onto stack
- X move.l d2,-(a7) * Push argc onto stack
- X
- X lea _BSSBAS,a3 * get base of BSS
- X moveq #0,d1
- X move.l #_BSSLEN,d0 * get length of BSS in longwords
- X bra.s clr_lp * and clear for length given
- Xclr_bss move.l d1,(a3)+
- Xclr_lp dbf d0,clr_bss
- X
- Xdomain:
- X jsr main(PC) * Call main(argc,argv)
- X moveq.l #0,d0 * Set successful status
- X bra.s exit2
- X
- Xexit:
- X_exit:
- XXCEXIT:
- X move.l 4(SP),d0 * Extract return code
- Xexit2:
- X move.l d0,-(a7)
- X move.l AbsExecBase.W,a6
- X move.l DOSBase(A4),a1
- X callsys CloseLibrary * Close Dos library
- X
- X*------ this rts sends us back to DOS:
- XexitToDOS:
- X MOVE.L (A7)+,D0
- X movea.l _StackPtr(a4),SP * Restore stack ptr
- X movem.l (a7)+,d1-d6/a0-a6
- X rts
- X
- X*-----------------------------------------------------------------------
- X* Global definitions
- X*
- X csect __MERGED,1,,2,2
- X
- X xdef NULL,SysBase,LoadAddress,DOSBase
- X xdef _oserr,_OSERR,_ONBREAK
- X xdef _ProgramName,_StackPtr,_base
- X
- XNULL dc.l 0
- X_base dc.l 0
- X_oserr equ *
- X_OSERR dc.l 0
- X_ONBREAK dc.l 0
- XSysBase dc.l 0
- XLoadAddress dc.l 0
- X_StackPtr dc.l 0
- XDOSBase dc.l 0
- X_ProgramName dc.l 0
- XDOSName dc.b 'dos.library',0
- X
- X END
- END_OF_FILE
- if test 6132 -ne `wc -c <'tiny.a'`; then
- echo shar: \"'tiny.a'\" unpacked with wrong size!
- fi
- # end of 'tiny.a'
- fi
- echo shar: End of archive 1 \(of 2\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked both archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
- Mail comments to the moderator at <amiga-request@uunet.uu.net>.
- Post requests for sources, and general discussion to comp.sys.amiga.
-